Core.Storage.Raw = function() {
	this.nps = {};
	this.root = {};
};

Core.Storage.Raw.prototype = {
	
	/**
	 * Clears singleton current state.
	 */
	__clear: function() {
		this.nps = {};
		this.root = {};
	},
	
	/**
	 * Returns value from the given array path. 
	 * If path doesn't exist returns undefined.
	 * @param Array arr - path.
	 */
	get: function(arr) {
		return Object.get(this.root, arr);
	},
	
	/**
	 * Sets value at the end of the array path.
	 * If path doesn't exist - creates it.
	 * Sets NP's listeners corresponding to the given path as dirty.
	 * 
	 * @param Array arr - path.
	 * @param Any value
	 */
	set: function(arr, value) {
		Object.set(this.root, arr, value);
		
		if(Core.App.isRunning()) {
			this._getNotifyPoint(arr).setListenersDirty();
		}
	},
	
	/**
	 * Registers listener under given array path.
	 * @param Array arr - path.
	 * @param Function fn - listener
	 */
	register: function(arr, fn) {
		this._getNotifyPoint(arr).register(fn);
	},
	
	/**
	 * Unregisters listener from the given array path.
	 * @param Array arr - path.
	 * @param Function fn - listener
	 */
	unregister: function(arr, fn) {
		this._getNotifyPoint(arr).unregister(fn);
	},
	
	/**
     * Returns NP for the given array path.
     * @param Array arr - path.
     */
	_getNotifyPoint: function(arr) {
		var base = Core.Storage.Rule.getNormalizedPath(arr);

	    if(!this.nps[base]) { this.nps[base] = new Core.Storage.NotifyPoint(); }
	    return this.nps[base];
	}

};

Core.Storage.Raw = Singleton.register("core.storage.raw", Core.Storage.Raw);